package com.fingard.dsp.bank.sepro;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptData;
import com.fingard.dsp.bank.dbobj.receipt.ReceiptDataHelper;
import com.fingard.dsp.bank.dbobj.receipt.ownact.OwnActData;
import com.fingard.dsp.bank.dbobj.receipt.ownact.OwnActHelper;
import com.fingard.dsp.bank.directConfig.ReceiptProConfig;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.bankInterface.IReceipt;
import com.fingard.dsp.bank.directbank.bankInterface.IReceiptPro;
import com.fingard.dsp.bank.reqrespobj.ReqRespHeader;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceiptDetail;
import com.fingard.dsp.bankset.BankFront;
import com.fingard.dsp.task.command.receipt.UploadReceiptFile;
import com.fingard.dsp.tcpserver.RequestNIO;
import com.fingard.luna.framework.boot.core.util.SpringContextHolder;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XmlTextReader;
import org.springframework.stereotype.Component;

@Component("ReceiptPro")
public class ReceiptPro {

	public static ReceiptProConfig getReceiptProConfig() throws Exception{
		String proCfgFile = FGBiz.dspCenter.rootDirPath + File.separator + "config" + File.separator + "ReceiptPro.xml";
    	ReceiptProConfig proConfig = new ReceiptProConfig();
    	proConfig.loadConfig(proCfgFile);
    	return proConfig;
	}
	
	private static TransIDHelper _idHelper = new TransIDHelper(1, 999);
	/**返回HHmmss+3位*/
	public static String getTransID(){
		return Format.Time6Format.format(new Date())+_idHelper.getNextIDStr();
	}
	
	private RequestNIO bizO;
	private BankFront bankFront;
	private ReqRespHeader reqHeader;
	public ReceiptPro(RequestNIO pBizO, BankFront pBankFront, ReqRespHeader pReqHeader){
		bizO = pBizO;
		bankFront = pBankFront;
		reqHeader = pReqHeader;
	}

	public RequestNIO getBizO() {
		return bizO;
	}

	public void setBizO(RequestNIO bizO) {
		this.bizO = bizO;
	}

	public BankFront getBankFront() {
		return bankFront;
	}

	public void setBankFront(BankFront bankFront) {
		this.bankFront = bankFront;
	}

	public ReqRespHeader getReqHeader() {
		return reqHeader;
	}

	public void setReqHeader(ReqRespHeader reqHeader) {
		this.reqHeader = reqHeader;
	}

	public ReceiptPro() {
	}

	/**正在执行的回单请求*/
	private static HashMap<String, Date> inProgressReq = new HashMap<String, Date>();
	
	/**执行回单下载*/
	public RetAtsReceipt execReceiptDown(String pClassName, XmlTextReader xmlReader) throws InstantiationException, IllegalAccessException, ClassNotFoundException, Exception{
		String logCode = "ReceiptPro.execReceiptDown";
		String classForName = pClassName;
		RetAtsReceipt retAts = new RetAtsReceipt(reqHeader);
		ReqQryReceipt tmpReqReceipt = new ReqQryReceipt(xmlReader, reqHeader);
		String reqKey = "";
		if(StringHelper.hasAnyChar(tmpReqReceipt.actNum) && StringHelper.hasAnyChar(tmpReqReceipt.dateFrom)){
			reqKey = tmpReqReceipt.actNum + "_" + bankFront.bankCode + "_" + tmpReqReceipt.dateFrom + "_" + tmpReqReceipt.dateTo;
		}else{
			reqKey = xmlReader.getSimpleText("AskNumber") + "_" + xmlReader.getSimpleText("PayDate") + "_" + bankFront.bankCode;
		}
		try{
			
			synchronized(inProgressReq){
				//判断是否有相同的回单查询请求在执行
				Date timeNow = new Date();
				if(inProgressReq.containsKey(reqKey)){
					Date lastReqTime = inProgressReq.get(reqKey);
					if(lastReqTime != null){
						double diffMins = DateHelper.getDifferMins(timeNow, lastReqTime);
						if(diffMins<30){//30分钟之内还在运行
							retAts.respCode = "0";
				            retAts.respInfo = "当前账号的回单下载正在执行中，开始执行时间："+Format.DateTimeFormat.format(lastReqTime);
				            retAts.writeRetToATS();
				            return retAts;
						}else{//到了30分钟，允许再次运行
							FGBiz.limitMsg.warning(logCode, reqKey+"已运行超过30分钟，允许再次运行");
						}
					}
				}
				inProgressReq.put(reqKey, timeNow);
				if(StringHelper.hasAnyChar(tmpReqReceipt.actNum) && StringHelper.hasAnyChar(tmpReqReceipt.dateFrom)){
					OwnActHelper ownHelper = new OwnActHelper();
					OwnActData ownData = new OwnActData();
					ownData.bankCode = bankFront.bankCode;
					ownData.corporation = bankFront.corporation;
					ownData.actGroup = bankFront.group;
					ownData.tenant = bankFront.tenant;
					ownData.actNum = tmpReqReceipt.actNum;
					ownData.areaCode = tmpReqReceipt.areaCode;
					ownData.areaName = tmpReqReceipt.areaName;
					ownData.cmptOrg = tmpReqReceipt.cmptOrg;
					ownHelper.insertIfNotExist(ownData);
				}
			}	
			
			if(!tmpReqReceipt.needChkData){
				RetAtsReceipt earlyComplete = new RetAtsReceipt(reqHeader);
				earlyComplete.respCode = "0";
				earlyComplete.respInfo = "后台处理中";
				earlyComplete.writeRetToATS();
				String earlyRetStr = earlyComplete.getRetAtsString();
				bizO.sbLog.append("先返回前端，再继续处理，返回报文："+earlyRetStr+"\r\n\r\n");
				bizO.writeRespBody(false, "", earlyRetStr);
			}
		
		
			String receiptVersion = DirectBase.getBankConfig(bankFront, reqHeader).getValueAsString("receiptVersion").toLowerCase();
			if("pro".equals(receiptVersion)){
				classForName = pClassName+"Pro";
				Class<?> bankClass = Class.forName(classForName);
	            if (bankClass != null) {
	            	ReceiptProConfig proConfig = ReceiptPro.getReceiptProConfig();
	            	
//	            	DirectBase proBase = (DirectBase) bankClass.newInstance();
					DirectBase proBase = (DirectBase) SpringContextHolder.getBean(reqHeader.bankCode + "ReceiptPro");
					proBase.reqHeader = reqHeader;
	            	proBase.bankFront = bankFront;
	            	proBase.setSbLog(bizO.sbLog);
	            	proBase.seqIDInner = bizO.seqIDInner;
	            	proBase.setLogFlushTime(bizO.connTime);
	            	proBase.WriteBankLogLn("receiptVersion:"+receiptVersion);
	            	IReceiptPro iReceiptPro = (IReceiptPro) proBase;

	            	if (StringHelper.hasAnyChar(tmpReqReceipt.dateFrom)) {
						//按日遍历进行下载
						Calendar tmpCalendarFrom = Calendar.getInstance();
						tmpCalendarFrom.setTime(tmpReqReceipt.getDateFrom());
						Calendar tmpCalendarTo = Calendar.getInstance();
						tmpCalendarTo.setTime(tmpReqReceipt.getDateTo());
						int tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
						int tmpIntTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
						while (tmpIntFrom <= tmpIntTo) {
							//int intFromStep = tmpIntFrom;
							//proBase.WriteBankLogLn(intFromStep + "的回单已执行过下载，如需重新获取，请删除文件");
							Date oneDay = tmpCalendarFrom.getTime();
							tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
							tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
							iReceiptPro.qryReceiptOneDay(proConfig, tmpReqReceipt, oneDay);
						}
					} else {
						iReceiptPro.qryReceiptOneDay(proConfig, tmpReqReceipt, new Date());
					}
	            }else{
	                retAts.respCode = "-1";
	                retAts.respInfo = "2."+reqHeader.bankCode + "未实现ReceiptPro接口" + reqHeader.transType;
	            }
			}else{
//				Class<?> bankClass = Class.forName(classForName);
//				DirectBase tmpDirectBase = (DirectBase) bankClass.newInstance();
				DirectBase tmpDirectBase = (DirectBase) SpringContextHolder.getBean(reqHeader.bankCode + "Receipt");
	            tmpDirectBase.reqHeader = reqHeader;
	            tmpDirectBase.bankFront = bankFront;
	            tmpDirectBase.setSbLog(bizO.sbLog);
	            tmpDirectBase.setLogFlushTime(bizO.connTime);
	            tmpDirectBase.seqIDInner = bizO.seqIDInner;
	            tmpDirectBase.WriteBankLogLn("receiptVersion:"+receiptVersion);
				IReceipt iReceipt = (IReceipt) tmpDirectBase;
				return iReceipt.qryReceipt(tmpReqReceipt);
			}
			if(tmpReqReceipt.needChkData){
				UploadReceiptFile upReceiptFile = new UploadReceiptFile();
				HashMap<String, String> params = new HashMap<String, String>();
				Date dateFrom = tmpReqReceipt.getDateFrom();
				Date dateTo = tmpReqReceipt.getDateTo();
				double diff1 = Math.ceil(DateHelper.getDifferDays(dateFrom, new Date()));
				int beginDay = Integer.parseInt(new DecimalFormat("0").format(diff1));
				double diff2 = Math.ceil(DateHelper.getDifferDays(dateTo, new Date()));
				int endDay = Integer.parseInt(new DecimalFormat("0").format(diff2));
				
				params.put("beginDayCount", beginDay+"");
				params.put("endDayCount", endDay+"");
				upReceiptFile.execTask(params);
				retAts = getReceiptChkData(tmpReqReceipt);
			}
			retAts.writeRetToATS();
			return retAts;
		}catch (ClassNotFoundException e) {
			FGBiz.limitMsg.exception(logCode, e, classForName);
            retAts.respCode = "-1";
            retAts.respInfo = reqHeader.bankCode + "未实现ReceiptPro接口" + reqHeader.transType;
            retAts.writeRetToATS();
            return retAts;
		}finally{
			synchronized(inProgressReq){
				//为兼容HashMap的线程不安全，不采用remove，而是置为null
				inProgressReq.put(reqKey, null);
			}
		}
	}
	
	private RetAtsReceipt getReceiptChkData(ReqQryReceipt pReqReceipt){
		RetAtsReceipt retAts = new RetAtsReceipt(reqHeader);
		retAts.respCode = "0";
		retAts.respInfo = "已接收请求";
		try{
			//按日遍历进行获取
	    	Calendar tmpCalendarFrom = Calendar.getInstance();
	        tmpCalendarFrom.setTime(pReqReceipt.getDateFrom());
	        Calendar tmpCalendarTo = Calendar.getInstance();
	        tmpCalendarTo.setTime(pReqReceipt.getDateTo());
	        int tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
	        int tmpIntTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
	        while (tmpIntFrom <= tmpIntTo) {
	        	Date oneDay = tmpCalendarFrom.getTime();
	            tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
	            tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
	            ReceiptDataHelper receiptHelper = null;
				try{
					receiptHelper = new ReceiptDataHelper(pReqReceipt.reqHeader.tenant, oneDay);
					ArrayList<ReceiptData> rDataList = receiptHelper.getUploadedDataList(pReqReceipt.actNum, oneDay);
					if(rDataList.size()>0){
						for(ReceiptData eachData : rDataList){
							RetAtsReceiptDetail rcptDt = new RetAtsReceiptDetail();
							rcptDt.oppActName = eachData.oppActName;
                    		rcptDt.oppActNum = eachData.oppActNum;
                    		if(eachData.amount != null){
                    			rcptDt.amount = Format.DecimalAmtFormat.format(eachData.amount);
                    		}
                    		rcptDt.summary = eachData.summary;
                    		rcptDt.istNbr = eachData.receiptNo + "_" + eachData.ownAct;
                            rcptDt.receiptNo = eachData.receiptNo;
                            rcptDt.busDate = Format.Date8Format.parse(String.valueOf(eachData.busDate));
                            rcptDt.busRef = eachData.busRef;
                            rcptDt.cur = eachData.cur;
                            rcptDt.moneyWay = eachData.moneyWay;
                            rcptDt.tranCode = eachData.tranCode;
                            rcptDt.receiptType = eachData.receiptType;
                            rcptDt.upFile = eachData.upFile;
                            retAts.writeRetDetail(rcptDt);
						}
					}
				}catch(Exception ex){
					FGBiz.limitMsg.exception("ReceiptPro.getReceiptChkData", ex);
				}finally{
					if(receiptHelper!=null){
						receiptHelper.close();
					}
				}
	        }
		}catch(Exception e){
			FGBiz.limitMsg.exception("ReceiptPro.getReceiptChkData", e);
            retAts.respCode = "-1";
            retAts.respInfo = LogHelper.getStackTrace(e);
		}
		retAts.writeRetToATS();
		
		return retAts;
	}
	
	/**删除临时文件，判断标准：以.tmp结尾，返回被删除的文件列表*/
	public static String deleteTmpFile(String pDirPath){
		StringBuilder sb = new StringBuilder();
		try{
			//删除临时文件
			File delDir = new File(pDirPath);
			if(delDir.exists()){
				File[] files = delDir.listFiles();
				if(files!=null && files.length > 0){
					for(File eachFile : files){
						if(eachFile.getName().toLowerCase().endsWith(".tmp")){
							eachFile.delete();
							sb.append("删除临时文件："+eachFile.getName()+"\r\n");
						}
					}
				}
			}
		}catch(Exception ex){
			FGBiz.limitMsg.exception("ReceiptPro.deleteTmpFile", ex);
			sb.append(LogHelper.getStackTrace(ex));
		}
		return sb.toString();
	}
}
